// 结绳语言编译插件
// 提供结绳语言的编译、构建和运行功能
import { TMakePlugin, PluginAPI, BuildTargetHandler, PluginLifecycleEvent } from '../plugin-system';
import * as fs from 'fs';
import * as path from 'path';
import { execSync } from 'child_process';

// 定义结绳构建插件主对象
const tieBuildPlugin: TMakePlugin = {
  metadata: {
    name: 'tie-build-plugin',
    version: '1.0.0',
    description: '结绳语言默认编译插件',
    author: 'TMake Team',
    isCore: true
  },

  // 初始化插件，注册构建目标和自定义函数
  init(api: PluginAPI) {
    // 注册结绳语言构建目标
    api.registerBuildTarget({
      name: 'tie',
      description: '结绳语言编译目标',
      type: 'compiler',
      extensions: ['.t'],  // 支持的文件扩展名
      isDefault: true,     // 是否为默认构建目标
      priority: 10,        // 构建优先级
      // 构建函数，负责编译结绳源文件
      build: async (api, sourceFiles, options) => {
        try {
          if (options.skipTieCompile) {
            const outputDir = path.resolve(options.output || './dist');
            const buildManager = new BuildManager(options.tieccDir);
            return await buildManager.compileCppFiles(outputDir, options);
          }
          
          // 调试输出辅助函数
          function debugLog(message: string, options?: {debug?: boolean}) {
            if (options?.debug) {
              console.log(`调试信息: ${message}`);
            }
          }

          debugLog('开始查找tiecc目录', {debug: options.debug});
          debugLog(`options.tieccDir = ${options.tieccDir}`, {debug: options.debug});
          debugLog(`api.getConfig().tieccDir = ${api.getConfig().tieccDir}`, {debug: options.debug});
          debugLog(`api.getConfig().tie?.tieccDir = ${api.getConfig().tie?.tieccDir}`, {debug: options.debug});
          debugLog(`process.env.TIECC_DIR = ${process.env.TIECC_DIR}`, {debug: options.debug});
          debugLog(`process.env.TIE_HOME = ${process.env.TIE_HOME}`, {debug: options.debug});
          
          // 解析 tiecc 编译器目录，按照优先级从高到低查找：
          // 1. 直接传入的选项
          // 2. 配置中的 tieccDir
          // 3. 配置中 tie 对象的 tieccDir
          // 4. 环境变量 TIECC_DIR
          // 5. TIE_HOME环境变量目录下的tiecc
          // 6. 相对路径tiecc
          // 7. Program Files目录下可能的tiecc位置
          // 8. 当前工作目录下的 tiecc 文件夹
          let tieccDir = options.tieccDir || 
                         api.getConfig().tieccDir || 
                         api.getConfig().tie?.tieccDir ||
                         process.env.TIECC_DIR;
          if (!tieccDir || !fs.existsSync(tieccDir)) {
            // 尝试TIE_HOME环境变量
            if (process.env.TIE_HOME) {
              const tieHomeTiecc = path.join(process.env.TIE_HOME, 'tiecc');
              if (fs.existsSync(tieHomeTiecc)) {
                tieccDir = tieHomeTiecc;
              }
            }
          }
          if (!tieccDir || !fs.existsSync(tieccDir)) {
            const possibleLocations = [
              path.join(process.cwd(), 'tiecc'),
              path.join(process.cwd(), '../tiecc'),
              path.join(process.env.ProgramFiles || 'C:\\Program Files', 'tiecc'),
              path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'tiecc')
            ];
            
            for (const loc of possibleLocations) {
              if (fs.existsSync(loc)) {
                tieccDir = loc;
                break;
              }
            }
          }
          
          // 如果所有位置都没找到，使用默认值
          if (!tieccDir) {
            tieccDir = path.join(process.cwd(), 'tiecc');
          }
          
          
          // 创建构建管理器实例
          const buildManager = new BuildManager(tieccDir);
          
          
          // 获取结绳相关配置，合并默认值和用户配置
          const tieConfig = api.getConfig().tie || {};
          const buildOptions = {
            output: options.output || api.getConfig().outputDir || './dist',
            package: options.package || tieConfig.package || 'main',
            outputFile: options.outputFile || api.getConfig().outputFile, // 添加outputFile属性
            debug: options.debug !== false,
            release: options.release === true,
            hardMode: options.hardMode === true,
            optimize: options.optimize || api.getConfig().optimizeLevel || 2,
            logLevel: options.logLevel || api.getConfig().logLevel || 'warning',
            platform: options.platform || tieConfig.platform || 'windows',
            lineMap: options.lineMap ?? tieConfig.lineMap ?? true,
            tieccDir: tieccDir,
            disableLint: options.disableLint || tieConfig.disableLint || [],
            customArgs: options.customArgs || tieConfig.extraArgs || [],
            compilerType: options.compilerType || api.getConfig().compiler,
            target: 'tie',
            targetOptions: options
          };
          
          
          // 处理源文件列表，如果未提供则尝试从默认源代码目录查找
          let filesToBuild = sourceFiles;
          if (!filesToBuild || filesToBuild.length === 0) {
            const projectSrcDir = path.join(process.cwd(), '源代码');
            if (fs.existsSync(projectSrcDir)) {
              filesToBuild = findTieFiles(projectSrcDir);
            }
          }
          
          
          // 调用构建管理器执行构建过程
          return await buildManager.build(filesToBuild, buildOptions);
        } catch (error: any) {
          console.error(`结绳编译失败: ${error.message}`);
          api.addError({ message: `编译失败: ${error.message}` });
          return false;
        }
      },
      // 清理构建产物的函数
      clean: async (api, options) => {
        try {
          const outputDir = options.output || api.getConfig().outputDir || './dist';
          
          if (fs.existsSync(outputDir)) {
            // 移除调试日志
            fs.rmSync(outputDir, { recursive: true, force: true });
            return true;
          }
          
          return true;
        } catch (error: any) {
          console.error(`清理失败: ${error.message}`);
          api.addError({ message: `清理失败: ${error.message}` });
          return false;
        }
      },
      // 获取合并后的配置信息
      getConfig: (api, options) => {
        return {
          ...api.getConfig(),
          ...options,
          tieccDir: options.tieccDir || api.getConfig().tieccDir || process.env.TIECC_DIR || path.join(process.cwd(), 'tiecc')
        };
      }
    });
    /**
     * 编译结绳文件
     * @description 使用结绳编译器编译指定的源文件
     * @param {string} sourceFile - 要编译的结绳源文件路径
     * @param {Object} [options] - 编译选项对象
     * @returns {boolean} 返回编译是否成功
     */
    api.registerFunction('compile_tie', (node: any, context: any) => {
      // 解析函数参数
      const sourceFile = node.params?.[0]?.value;
      const options = node.params?.[1]?.type === 'object' ? 
        node.params[1].params?.reduce((acc: any, param: any) => {
          if (param.key && param.value) {
            acc[param.key.value] = param.value.value;
          }
          return acc;
        }, {}) : {};
      
      // 验证参数
      if (!sourceFile) {
        throw new Error('compile_tie 函数需要源文件参数');
      }
      
      // 执行构建目标
      return api.executeBuildTarget('tie', [sourceFile], options);
    });

    
    /**
     * 编译并运行结绳代码
     * @description 编译指定的结绳源文件并运行生成的可执行文件
     * @param {string} sourceFile - 要编译并运行的结绳源文件路径
     * @param {Object} [options] - 编译和运行选项对象
     * @returns {string} 返回程序运行的输出结果
     */
    api.registerFunction('编译并运行结绳代码', async (node: any, context: any) => {
      // 解析函数参数
      const sourceFile = node.params?.[0]?.value;
      const options = node.params?.[1]?.type === 'object' ? 
        node.params[1].params?.reduce((acc: any, param: any) => {
          if (param.key && param.value) {
            acc[param.key.value] = param.value.value;
          }
          return acc;
        }, {}) : {};
      // 验证参数
      if (!sourceFile) {
        throw new Error('编译并运行结绳代码 函数需要源文件参数');
      }
      
      // 先编译结绳文件
      const compileResult = await api.executeBuildTarget('tie', [sourceFile], options);
      
      if (!compileResult) {
        throw new Error('编译失败，无法运行程序');
      }
      
      const outputDir = options.output || './dist';
      let programName = options.package || 'main';
      
      // 如果options中有outputFile值，使用它（去掉可能的路径部分，只保留文件名）
      if (options.outputFile) {
        programName = path.basename(options.outputFile, '.exe');
      }
      
      const programPath = path.join(outputDir, `${programName}.exe`);
      
      // 执行编译后的程序
      if (fs.existsSync(programPath)) {
        try {
          const output = execSync(`"${programPath}"`, { encoding: 'utf-8' });
          return output;
        } catch (error: any) {
          console.error(`程序运行失败: ${error.message}`);
          throw new Error(`程序运行失败: ${error.message}`);
        }
      } else {
        throw new Error(`编译后的程序不存在: ${programPath}`);
      }
    });
    /**
     * 设置tiecc编译器目录
     * @description 设置结绳编译器的安装目录路径
     * @param {string} [tieccDir] - tiecc编译器目录路径，如果未提供则使用默认路径
     * @returns {string} 返回最终设置的tiecc目录路径
     */
    api.registerFunction('设置tiecc目录', (node: any, context: any) => {
      let tieccDir;
      if (node.params && node.params.length > 0) {
        tieccDir = node.params[0].value || node.params[0];
      }
      
      const defaultTieccDir = path.join(process.cwd(), 'tiecc');
      const finalTieccDir = tieccDir || defaultTieccDir;
      if (!fs.existsSync(finalTieccDir)) {
        console.warn(`警告: 指定的tiecc目录不存在: ${finalTieccDir}`);
      }
      
      // 设置环境变量，以便后续构建过程使用
      process.env.TIECC_DIR = finalTieccDir;
      
      // 返回设置的目录路径
      return finalTieccDir;
    });
  }
};


// 递归查找目录中的所有结绳源文件(.t)
function findTieFiles(directory: string): string[] {
  const tieFiles: string[] = [];
  
  // 递归搜索目录的内部函数
  const searchDirectory = (dir: string) => {
    if (!fs.existsSync(dir)) return;
    
    try {
      const files = fs.readdirSync(dir);
      for (const file of files) {
        // 确保文件名是有效的字符串
        if (typeof file === 'string' && file) {
          const filePath = path.join(dir, file);
          try {
            const stats = fs.statSync(filePath);
            
            // 如果是子目录则递归搜索，否则检查是否为结绳文件
            if (stats.isDirectory()) {
              searchDirectory(filePath);
            } else if (file.endsWith('.t')) {
              tieFiles.push(filePath);
            }
          } catch (statError) {
            console.warn(`无法获取文件状态: ${filePath}, 跳过`);
          }
        }
      }
    } catch (err) {
      console.error(`读取目录失败: ${dir}, 错误: ${err}`);
    }
  };
  
  // 开始搜索
  searchDirectory(directory);
  return tieFiles;
}


// 构建前钩子 - 仅在非静默模式下输出构建开始信息
tieBuildPlugin[PluginLifecycleEvent.BEFORE_BUILD] = function(api: PluginAPI, options: any) {
  if (!options?.silent) {
    console.log('开始构建结绳项目...');
  }
};

// 构建后钩子 - 根据构建结果输出相应信息
tieBuildPlugin[PluginLifecycleEvent.AFTER_BUILD] = function(api: PluginAPI, success: boolean) {
  if (success) {
    // 仅在非静默模式下输出成功消息
    if (!api.getConfig().silent) {
      console.log('结绳项目构建成功!');
    }
  } else {
    // 保留错误信息
    console.error('结绳项目构建失败!');
  }
};


// 构建管理器类 - 负责协调结绳文件的编译过程
class BuildManager {
  private tieccDir: string; // tiecc编译器目录路径
  
  // 根据debug模式控制日志输出
  private debugLog(message: string, debug: boolean): void {
    if (debug) {
      console.log(`调试信息: ${message}`);
    }
  }

  // 构造函数
  constructor(tieccDir: string) {
    this.tieccDir = tieccDir;
  }

  // 主构建方法，协调整个编译流程
  async build(tFiles: string[], options: any): Promise<boolean> {
    try {
      const debug = options?.debug || false;
      
      // 检查tiecc目录是否存在
      if (!fs.existsSync(this.tieccDir)) {
        console.error(`错误: tiecc目录不存在: ${this.tieccDir}`);
        return false;
      }
      
      // 构建tiecc编译命令并执行
      this.debugLog(`开始构建tiecc编译命令`, debug);
      const tieccCommand = this.buildTieccCommand(options, tFiles);
      this.debugLog(`tiecc编译命令: ${tieccCommand.join(' ')}`, debug);
      
      this.debugLog(`开始执行tiecc编译`, debug);
      const result = this.executeCommand(tieccCommand, debug);
      if (!result.success) {
        console.error('结绳编译失败');
        return false;
      }
      this.debugLog(`tiecc编译成功完成`, debug);
      
      // 编译生成的C++文件
      this.debugLog(`开始编译生成的C++文件`, debug);
      const cppResult = await this.compileCppFiles(options.output, options);
      if (!cppResult) {
        console.error('C++文件编译失败');
        return false;
      }
      this.debugLog(`C++文件编译成功完成`, debug);
      
      return true;
    } catch (error: any) {
      console.error(`构建过程中发生错误: ${error.message}`);
      return false;
    }
  }

  // 构建tiecc编译器命令行参数
  private buildTieccCommand(options: any, tFiles: string[]): string[] {
    // 获取tiecc可执行文件路径
    const tieccExe = path.join(this.tieccDir, this.getTieccExecutable(options.platform));
    const command: string[] = [tieccExe];

    
    // 设置输出目录
    command.push('-o', options.output);
    
    // 设置包名
    command.push('-p', options.package);
    
    // 设置目标平台
    command.push('--platform', options.platform);
    
    // 设置构建模式（release/debug/hard-mode）
    if (options.release) {
      command.push('--release');
    } else if (!options.debug && !options.hardMode) {
      command.push('--debug'); 
    }
    
    if (options.hardMode) {
      command.push('--hard-mode');
    }
    
    // 设置优化级别
    command.push('--optimize', options.optimize.toString());
    
    // 添加禁用lint选项
    if (options.disableLint) {
      for (const lint of options.disableLint) {
        command.push('--disable-lint', lint);
      }
    }
    
    // 添加其他选项
    command.push('--log-level', options.logLevel);
    if (options.lineMap) {
      command.push('--line-map', options.lineMap);
    }
    if (options.customArgs) {
      command.push(...options.customArgs);
    }
    
    // 添加源文件路径
    command.push(...tFiles);
    
    return command;
  }

  // 获取tiecc可执行文件名
  private getTieccExecutable(platform: string): string {
    // 当前仅支持Windows平台，返回固定的可执行文件名
    return 'tiecc.exe';
  }

  // 执行外部命令并返回执行结果
  private executeCommand(command: string[], debug: boolean = false): { success: boolean; output: string } {
    try {
      const commandStr = command.join(' ');
      this.debugLog(`执行命令: ${commandStr}`, debug);
      const output = execSync(commandStr, { encoding: 'utf-8' });
      this.debugLog(`命令执行成功`, debug);
      if (output && output.trim()) {
        this.debugLog(`命令输出:\n${output.trim()}`, debug);
      }
      return { success: true, output };
    } catch (error: any) {
      const errorOutput = error.stderr || error.message;
      console.error(`命令执行失败:\n${errorOutput}`);
      this.debugLog(`命令输出(错误):\n${errorOutput}`, debug);
      return { success: false, output: errorOutput };
    }
  }

  // 编译生成的C++文件
  public async compileCppFiles(outputDir: string, options: any): Promise<boolean> {
    try {
      const debug = options?.debug || false;
      
      // 查找需要编译的C++文件
      this.debugLog(`在目录 ${outputDir} 中查找C++文件`, debug);
      const cppFiles = this.findCppFiles(outputDir);
      if (cppFiles.length === 0) {
        this.debugLog(`未找到需要编译的C++文件`, debug);
        return true;
      }

      this.debugLog(`找到 ${cppFiles.length} 个C++文件: ${cppFiles.join(', ')}`, debug);
      
      // 获取编译器和编译参数
      const compiler = this.getCppCompiler(options);
      const compilerArgs = this.getCompilerArgs(options, cppFiles, outputDir);
      
      this.debugLog(`使用编译器: ${compiler}`, debug);
      this.debugLog(`编译器参数: ${compilerArgs.join(' ')}`, debug);
      
      // 执行编译命令
      const result = this.executeCommand([compiler, ...compilerArgs], debug);
      
      if (result.success) {
        this.debugLog(`C++文件编译成功`, debug);
      } else {
        this.debugLog(`C++文件编译失败`, debug);
      }
      
      return result.success;
    } catch (error: any) {
      console.error(`编译.cpp文件失败: ${error.message}`);
      return false;
    }
  }

  // 获取C++编译器路径
  private getCppCompiler(options: any): string {
    if (options.compilerType) {
      // 处理MSVC编译器特殊情况
      if (options.compilerType.toLowerCase() === 'msvc') {
        return this.findMsvcCompiler();
      }
      return options.compilerType;
    }
    
    // 默认使用g++编译器
    return 'g++';
  }
  private findMsvcCompiler(): string {
    // 尝试常见的MSVC编译器位置
    const possiblePaths = [
      // Visual Studio 2022常见路径
      path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.34.31933\\bin\\Hostx64\\x64\\cl.exe'),
      path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Microsoft Visual Studio\\2022\\Professional\\VC\\Tools\\MSVC\\14.34.31933\\bin\\Hostx64\\x64\\cl.exe'),
      // Visual Studio 2019常见路径
      path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Microsoft Visual Studio\\2019\\Community\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe'),
      path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Microsoft Visual Studio\\2019\\Professional\\VC\\Tools\\MSVC\\14.29.30133\\bin\\Hostx64\\x64\\cl.exe'),
      // 如果环境变量中有VCToolsInstallDir，使用它
      process.env.VCToolsInstallDir ? path.join(process.env.VCToolsInstallDir, 'bin\\Hostx64\\x64\\cl.exe') : undefined
    ].filter(Boolean) as string[];

    // 检查是否存在可用的cl.exe
    for (const clPath of possiblePaths) {
      if (fs.existsSync(clPath)) {
        return clPath;
      }
    }

    // 如果找不到，至少返回'cl.exe'，依赖系统PATH环境变量
    console.warn('未找到MSVC编译器(cl.exe)，将使用系统PATH中的cl.exe');
    return 'cl.exe';
  }

  private getMsvcIncludePaths(): string[] {
    const includePaths: string[] = [];
    
    // 添加调试日志
    console.log('开始查找MSVC标准库和Windows SDK路径...');
    
    // 尝试获取常见的Visual Studio和Windows SDK路径
    const programFiles = process.env.ProgramFiles || 'C:\\Program Files';
    const programFilesX86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)';
    
    // 显示环境变量信息用于调试
    console.log(`环境变量VCToolsInstallDir: ${process.env.VCToolsInstallDir}`);
    console.log(`ProgramFiles: ${programFiles}`);
    console.log(`ProgramFiles(x86): ${programFilesX86}`);
    
    // 直接尝试一些常见的MSVC路径模式 - 特别关注VS 2019（编译器版本19.29.30159）
    const commonMsvcPaths = [
      // 尝试VCToolsInstallDir环境变量
      process.env.VCToolsInstallDir ? path.join(process.env.VCToolsInstallDir, 'include') : null,
      // VS 2019的常见路径模式（基于编译器版本19.29.30159）
      path.join(programFiles, 'Microsoft Visual Studio', '2019', 'Community', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      path.join(programFiles, 'Microsoft Visual Studio', '2019', 'Professional', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      path.join(programFiles, 'Microsoft Visual Studio', '2019', 'Enterprise', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      path.join(programFiles, 'Microsoft Visual Studio', '2019', 'BuildTools', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      // x86路径 - VS 2019
      path.join(programFilesX86, 'Microsoft Visual Studio', '2019', 'Community', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      path.join(programFilesX86, 'Microsoft Visual Studio', '2019', 'Professional', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      path.join(programFilesX86, 'Microsoft Visual Studio', '2019', 'Enterprise', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      // VS 2022的常见路径模式
      path.join(programFiles, 'Microsoft Visual Studio', '2022', 'Community', 'VC', 'Tools', 'MSVC', '14.34.31933', 'include'),
      path.join(programFiles, 'Microsoft Visual Studio', '2022', 'Professional', 'VC', 'Tools', 'MSVC', '14.34.31933', 'include'),
      // 其他可能的位置
      path.join(programFilesX86, 'Microsoft Visual C++ Build Tools', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include'),
      path.join(programFiles, 'Microsoft Visual C++ Build Tools', 'VC', 'Tools', 'MSVC', '14.29.30133', 'include')
    ];
    
    // 检查常见的MSVC路径
    for (const msvcPath of commonMsvcPaths) {
      if (msvcPath && fs.existsSync(msvcPath)) {
        console.log(`找到MSVC标准库路径: ${msvcPath}`);
        includePaths.push(msvcPath);
        break; // 找到一个就足够了
      }
    }
    
    // 如果没找到，尝试一种更通用的方法 - 查找最近安装的Visual Studio
    if (includePaths.length === 0) {
      const vsRoots = [
        path.join(programFiles, 'Microsoft Visual Studio'),
        path.join(programFilesX86, 'Microsoft Visual Studio')
      ];
      
      for (const vsRoot of vsRoots) {
        if (fs.existsSync(vsRoot)) {
          try {
            // 查找最近的Visual Studio版本
            const years = fs.readdirSync(vsRoot).filter(y => /^\d{4}$/.test(y)).sort((a, b) => parseInt(b) - parseInt(a));
            for (const year of years) {
              const yearPath = path.join(vsRoot, year);
              const editions = fs.readdirSync(yearPath);
              for (const edition of editions) {
                const editionPath = path.join(yearPath, edition);
                const msvcToolsRoot = path.join(editionPath, 'VC', 'Tools', 'MSVC');
                
                if (fs.existsSync(msvcToolsRoot)) {
                  const toolsets = fs.readdirSync(msvcToolsRoot).filter(t => /^\d+\.\d+\.\d+\.\d+$/.test(t)).sort();
                  if (toolsets.length > 0) {
                    const latestToolset = toolsets[toolsets.length - 1];
                    const msvcIncludePath = path.join(msvcToolsRoot, latestToolset, 'include');
                    if (fs.existsSync(msvcIncludePath)) {
                      console.log(`找到MSVC标准库路径: ${msvcIncludePath}`);
                      includePaths.push(msvcIncludePath);
                      break;
                    }
                  }
                }
              }
              if (includePaths.length > 0) break;
            }
          } catch (e: any) {
            console.warn('查找Visual Studio路径时出错:', e.message);
          }
        }
        if (includePaths.length > 0) break;
      }
    }
    
    // 检查Windows SDK路径
    const windowsSdkPaths = [
      path.join(programFilesX86, 'Windows Kits', '10', 'Include'),
      path.join(programFiles, 'Windows Kits', '10', 'Include')
    ];
    
    for (const sdkRoot of windowsSdkPaths) {
      if (fs.existsSync(sdkRoot)) {
        console.log(`找到Windows SDK根目录: ${sdkRoot}`);
        // 找到最新的SDK版本
        try {
          const versions = fs.readdirSync(sdkRoot).filter(v => /^\d+\.\d+\.\d+\.\d+$/.test(v));
          if (versions.length > 0) {
            const latestVersion = versions.sort().pop()!;
            const sdkIncludePath = path.join(sdkRoot, latestVersion);
            if (fs.existsSync(sdkIncludePath)) {
              // 添加um和shared目录
              const umPath = path.join(sdkIncludePath, 'um');
              const sharedPath = path.join(sdkIncludePath, 'shared');
              if (fs.existsSync(umPath)) {
                console.log(`添加Windows SDK um路径: ${umPath}`);
                includePaths.push(umPath);
              }
              if (fs.existsSync(sharedPath)) {
                console.log(`添加Windows SDK shared路径: ${sharedPath}`);
                includePaths.push(sharedPath);
              }
            }
          }
        } catch (e: any) {
          console.warn('无法读取Windows SDK版本目录:', e.message);
        }
      }
    }
    
    // 如果找不到MSVC标准库路径，添加一些可能的通用路径作为备选
    if (includePaths.length === 0 || !includePaths.some(p => p.includes('MSVC'))) {
      console.warn('未找到MSVC标准库路径，尝试使用备选方案');
      
      // 尝试使用一些通用的Visual C++ Redistributable路径
      const redistPaths = [
        path.join(programFiles, 'Microsoft Visual Studio', '2022', 'BuildTools', 'VC', 'Tools', 'MSVC'),
        path.join(programFilesX86, 'Microsoft Visual C++', 'Redist')
      ];
      
      for (const redistPath of redistPaths) {
        if (fs.existsSync(redistPath)) {
          console.log(`找到Visual C++路径: ${redistPath}`);
          // 尝试在这些路径中查找include目录
          try {
            const subDirs = fs.readdirSync(redistPath);
            for (const subDir of subDirs) {
              const includePath = path.join(redistPath, subDir, 'include');
              if (fs.existsSync(includePath)) {
                console.log(`添加备选MSVC路径: ${includePath}`);
                includePaths.push(includePath);
                break;
              }
            }
          } catch (e: any) {
            console.warn('读取Visual C++路径时出错:', e.message);
          }
        }
      }
    }
    
    console.log(`最终的包含路径列表: ${JSON.stringify(includePaths)}`);
    return includePaths;
  }

  // 生成C++编译器命令行参数
  private getCompilerArgs(options: any, cppFiles: string[], outputDir: string): string[] {
    const args: string[] = [];
    const compilerType = (options.compilerType || '').toLowerCase() || this.getCppCompiler(options).toLowerCase();
    const isMsvc = compilerType.includes('msvc') || compilerType.includes('cl.exe');
    
    // 添加包含目录
    const includeDir = path.join(outputDir, 'src');
    if (isMsvc) {
      args.push(`/I${includeDir}`);
      args.push('/EHsc'); // 启用异常处理
      
      // 添加MSVC标准库和Windows SDK的包含路径
      const msvcIncludePaths = this.getMsvcIncludePaths();
      for (const includePath of msvcIncludePaths) {
        // 为包含空格的路径添加引号
        if (includePath.includes(' ')) {
          args.push(`/I"${includePath}"`);
        } else {
          args.push(`/I${includePath}`);
        }
      }
    } else {
      args.push('-I', includeDir);
    }
    
    // 添加调试信息选项
    if (options.debug) {
      if (isMsvc) {
        args.push('/Zi'); // 生成调试信息
        args.push('/Od');
      } else {
        args.push('-g');
      }
    } else if (options.optimize > 0) {
      // 仅在非调试模式下添加优化选项，避免冲突
      if (isMsvc) {
        // MSVC优化级别：1, 2, 3, s(最小化大小)
        const optLevel = Math.min(options.optimize, 3);
        args.push(`/O${optLevel}`);
        if (optLevel >= 2) {
          args.push('/Oi'); // 启用内联函数
        }
      } else {
        args.push(`-O${options.optimize}`);
      }
    }
    
    // 设置C++标准版本
    if (!isMsvc) {
      args.push('-std=c++17');
    } else {
      args.push('/std:c++17');
    }
    
    // MSVC特定的附加选项
    if (isMsvc) {
      args.push('/W3'); // 警告级别
      args.push('/utf-8'); // 使用UTF-8编码
      // 添加运行时库
      if (options.debug) {
        args.push('/MDd'); // 调试多线程DLL
      } else {
        args.push('/MD'); // 发布多线程DLL
      }
    }
    
    // 添加源文件
    args.push(...cppFiles);
    
    // 设置输出文件 - 优先使用options中的outputFile值
    let outputFileName = options.package;
    
    // 如果options中有outputFile值，使用它（去掉可能的路径部分，只保留文件名）
    if (options.outputFile) {
      outputFileName = path.basename(options.outputFile, '.exe');
    }
    
    const outputFile = path.join(outputDir, `${outputFileName}.exe`);
    if (isMsvc) {
      args.push('/Fe:', outputFile); // 修正MSVC输出文件参数格式
    } else {
      args.push('-o', outputFile);
    }
    
    // 添加链接器选项
    if (isMsvc) {
      args.push('/link');
      args.push('/SUBSYSTEM:CONSOLE'); // 控制台应用程序
    }
    
    return args;
  }

  // 递归查找目录中的所有C++源文件(.cpp)
  private findCppFiles(directory: string): string[] {
    const cppFiles: string[] = [];
    
    // 递归遍历目录的内部函数
    function walkDir(filePath: string) {
      if (!fs.existsSync(filePath)) return;
      
      try {
        const files = fs.readdirSync(filePath);
        
        for (const file of files) {
          // 确保文件名是有效的字符串
          if (typeof file === 'string' && file) {
            const fullPath = path.join(filePath, file);
            try {
              const stat = fs.statSync(fullPath);
              
              // 如果是子目录则递归搜索，否则检查是否为C++文件
              if (stat.isDirectory()) {
                walkDir(fullPath);
              } else if (file.endsWith('.cpp')) {
                cppFiles.push(fullPath);
              }
            } catch (statError) {
              console.warn(`无法获取文件状态: ${fullPath}, 跳过`);
            }
          }
        }
      } catch (err) {
        console.error(`读取目录失败: ${filePath}, 错误: ${err}`);
      }
    }
    
    // 开始遍历目录
    if (fs.existsSync(directory)) {
      walkDir(directory);
    }
    
    return cppFiles;
  }
}

// 导出插件
export default tieBuildPlugin;